import numpy as np
import pandas as pd
# 读取数据
wine_data = pd.read_csv('wine.data', header=None)
# 提取类别标签为 1 和 2 的数据
class_1_data = wine_data[wine_data[0] == 1].drop(0, axis=1).values
class_2_data = wine_data[wine_data[0] == 2].drop(0, axis=1).values
# 合并数据
new_wine_data = np.vstack((class_1_data, class_2_data))

# PCA 降维
def pca(data, n_components=2):
    # 计算均值
    mean = np.mean(data, axis=0)
    # 数据标准化
    centered_data = data - mean
    # 计算协方差矩阵
    covariance_matrix = np.cov(centered_data.T)
    # 计算特征值和特征向量
    eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix)
    # 对特征值进行排序
    sorted_indices = np.argsort(eigenvalues)[::-1]
    sorted_eigenvectors = eigenvectors[:, sorted_indices]
    # 选择前 n 个特征向量
    selected_eigenvectors = sorted_eigenvectors[:, :n_components]
    # 进行降维
    reduced_data = np.dot(centered_data, selected_eigenvectors)
    return reduced_data

pca_result = pca(new_wine_data)

# LDA 降维
def lda(data, labels, n_components=1):
    # 计算类别均值
    class_means = []
    unique_labels = np.unique(labels)
    for label in unique_labels:
        class_data = data[labels == label]
        class_mean = np.mean(class_data, axis=0)
        class_means.append(class_mean)
    # 计算总体均值
    overall_mean = np.mean(data, axis=0)
    # 计算类间散度矩阵
    Sb = np.zeros((data.shape[1], data.shape[1]))
    for i, mean in enumerate(class_means):
        n = data[labels == unique_labels[i]].shape[0]
        diff = (mean - overall_mean).reshape(-1, 1)
        Sb += n * np.dot(diff, diff.T)
    # 计算类内散度矩阵
    Sw = np.zeros((data.shape[1], data.shape[1]))
    for i, label in enumerate(unique_labels):
        class_data = data[labels == label]
        class_mean = class_means[i]
        diff = class_data - class_mean
        Sw += np.dot(diff.T, diff)
    # 计算广义特征值和特征向量
    eigenvalues, eigenvectors = np.linalg.eig(np.linalg.inv(Sw).dot(Sb))
    # 对特征值进行排序
    sorted_indices = np.argsort(eigenvalues)[::-1]
    sorted_eigenvectors = eigenvectors[:, sorted_indices]
    # 选择前 n 个特征向量
    selected_eigenvectors = sorted_eigenvectors[:, :n_components]
    # 进行降维
    reduced_data = np.dot(data, selected_eigenvectors)
    return reduced_data

# 生成类别标签
labels = np.concatenate([np.zeros(class_1_data.shape[0]), np.ones(class_2_data.shape[0])])
lda_result = lda(new_wine_data, labels)

# 输出 PCA 降维后的两维特征
print("PCA 降维后的两维特征：")
print(pca_result[:5])

# 输出 LDA 降维后的结果
print("LDA 降维后的结果：")
print(lda_result[:5])